/****************************************************************************
*  Title: design.sc
*  Author: Bryant Smith
*  Date: 04/16/2011
*  Description: Main behavior for parity generator / encoder
*               Accepts stream of input bytes and outputs encoded bytes
*               Input set even or odd parity 
****************************************************************************/

import "c_queue";
import "imageProcessor";
import "imageMatcher";
import "laneDetector";
import "cornerDetector";

#define IMG_ROWS 480
#define IMG_CLMS 640

const unsigned long QUEUE_SIZE = 1000;


// Left Image processing
behavior PE1(i_receiver InQueue, i_sender CornerOutQueue, i_sender LaneInQueue)
{
	unsigned char imageBuffer[IMG_ROWS][IMG_CLMS];
	unsigned char imageSmooth[IMG_ROWS][IMG_CLMS];
	double cornerImg[IMG_ROWS][IMG_CLMS];
	
	receiveImage      imgRcvr(InQueue, imageBuffer);
	preProcessImageL  preProc(imageBuffer, imageSmooth, LaneInQueue);
	harrisCorner	  corner(imageSmooth, cornerImg);
	normalizeSender   imgSender(cornerImg, CornerOutQueue);
	
	void main(void)
	{
		while(1){
			printf("waiting image processor\n");
			imgRcvr.main();
			printf("not waiting image processor\n");
			preProc.main();
			corner.main();	
			imgSender.main();
			printf("reached end image processor\n");
		}
	}
};


// Right Image processing
behavior PE2(i_receiver InQueue, i_sender CornerOutQueue)
{
	unsigned char imageBuffer[IMG_ROWS][IMG_CLMS];
	unsigned char imageSmooth[IMG_ROWS][IMG_CLMS];
	double cornerImg[IMG_ROWS][IMG_CLMS];
	
	receiveImage      imgRcvr(InQueue, imageBuffer);
	preProcessImageR  preProc(imageBuffer, imageSmooth);
	harrisCorner	  corner(imageSmooth, cornerImg);
	normalizeSender   imgSender(cornerImg, CornerOutQueue);
	
	void main(void)
	{
		while(1){
			imgRcvr.main();
			preProc.main();
			corner.main();	
			imgSender.main();
		}
	}
};


// Lane Detection
behavior PE3(i_receiver LaneInQueue, i_sender LaneOutQueue)
{
	unsigned char imageBuf[IMG_ROWS][IMG_CLMS];
	double sobelG[IMG_ROWS][IMG_CLMS];
	
	receiveImage  imgRcvr(LaneInQueue, imageBuf);
	sobelEdge     sobel(imageBuf, sobelG);
	houghLine     hough(sobelG, LaneOutQueue);	

	void main(void)
	{
		while(1){
			imgRcvr.main();
			sobel.main();
			hough.main();
		}
	}
};


// Image Matching
behavior PE4(i_receiver CornerOutQueueL, i_receiver CornerOutQueueR, i_sender OutQueue)
{
	unsigned char image_buffer_l[IMG_ROWS][IMG_CLMS];
	unsigned char image_buffer_r[IMG_ROWS][IMG_CLMS];

	matchReceive  imgRcvr(CornerOutQueueL, CornerOutQueueR, image_buffer_l, image_buffer_r);
	normalizeSnd  imgSender(image_buffer_l, OutQueue);

	void main(void) 
	{			
		while(1){
			imgRcvr.main();
			imgSender.main();
		}
	}
};



// notice for the right image we are writing to a queue which
// has no reders, this was to re-use the same PE for both the right 
// and left image processing. but we only need one for lane detection
behavior design(i_receiver InQueueL, i_receiver InQueueR, i_sender OutQueue,
		i_sender LaneOutQueue)
{
	// Design channls
	c_queue LaneInQueue((QUEUE_SIZE));
	c_queue LaneInQueueR((QUEUE_SIZE));
	c_queue CornerOutQueueL((QUEUE_SIZE));
	c_queue CornerOutQueueR((QUEUE_SIZE));
	
	PE1     peL(InQueueL, CornerOutQueueL, LaneInQueue);
	PE2     peR(InQueueR, CornerOutQueueR);  // note queue for lane detector is not used here
	PE3		pe3(LaneInQueue, LaneOutQueue);
	PE4     pe4(CornerOutQueueL, CornerOutQueueR, OutQueue);

	void main (void)
	{
		par {
			peL.main();
			peR.main();
			pe3.main();
			pe4.main();
		}
	}
};


